package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.User;
import com.example.demo.entity.vo.LoginInput;
import com.example.demo.entity.vo.LoginOutput;
import com.example.demo.exception.CmsException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.utils.Md5Util;
import com.example.demo.utils.RedisUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author chen huilong
 * @since 2022-10-04
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    @Resource
    private RedisUtil redisUtil;

    @Override
    public void register(User user) {
        baseMapper.insert(user);
    }

    @Override
    public LoginOutput login(LoginInput loginInput, HttpServletRequest request, HttpServletResponse response) {
        // 获取用户名和密码
        String user_number = loginInput.getUserNumber();
        String password = loginInput.getPassword();
        // 判断参数是否完整
        if (user_number == null || password == null) {
            throw new CmsException(ErrorCode.INCOMPLETE_PARAMETER);
        }
        // 访问数据库，查询用户信息
        User user = new User();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_number", user_number);
        user = baseMapper.selectOne(wrapper);
        // 判断用户是否存在
        if (user == null) {
            throw new CmsException(ErrorCode.NO_SUCH_USER);
        } else if (!user.getPassword().matches(Md5Util.MD5(password))) {
            // 判断密码是否正确（这里为了省事，在数据库中存的是MD5加密后的，前端传送明文，后端加密一次在比较）
            throw new CmsException(ErrorCode.WRONG_ACCOUNT_OR_PASSWORD);
        }
        // 用户账号已停用
        if (!user.getStatus()) {
            throw new CmsException(ErrorCode.NO_SUCH_USER);
        }
        String access_token = UUID.randomUUID() + "";
        // 获取session
        HttpSession session = request.getSession();
        // 使用access_token作为sessionId，将用户实体存入session
        session.setAttribute(access_token, user);
        // 设置session过期时间
        session.setMaxInactiveInterval(30 * 60);
        // 将access_token通过cookie传回客户端
        Cookie cookie = new Cookie("access_token", access_token);
        response.addCookie(cookie);
        LoginOutput loginOutput = new LoginOutput();
        loginOutput.of(user);
        return loginOutput;
    }


    @Override
    public User getUserInfo(String token, HttpServletRequest request) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(token);
        return user;
    }

    @Override
    public void setVerificationCode(String token, String verificationCode) {
        if (verificationCode.length() != 4) {
            throw new CmsException(ErrorCode.VERIFICATION_CODE_LENGTH_WRONG);
        }
        User user = (User) redisUtil.get(token);
        user.setVerificationCode(verificationCode);
        baseMapper.updateById(user);
    }

    @Override
    public void modifyStuInfo(String token, User user) {
        User userEntity = (User) redisUtil.get(token);
        if (!"管理员".equals(userEntity.getUserRole())) {
            throw new CmsException(ErrorCode.REQUIRE_SUPER_MANAGER);
        }
        if ("0".equals(user.getGender()) && "1".equals(user.getGender())) {
            throw new CmsException(ErrorCode.GENDER_WRONG);
        }
        int rows = baseMapper.updateById(user);
        if (rows == 0) {
            throw new CmsException(ErrorCode.DATA_BASE_EXCEPTION);
        }
    }

    @Override
    public void changePassword(Map<String, Object> input, HttpServletRequest request) {
        String oldPassword = (String) input.get("oldPassword");
        String newPassword1 = (String) input.get("newPassword1");
        String newPassword2 = (String) input.get("newPassword2");

        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(request.getHeader("access_token"));

        if (oldPassword == null || newPassword1 == null || newPassword2 == null) {
            throw new CmsException(ErrorCode.INCOMPLETE_PARAMETER);
        }

        if (!newPassword1.equals(newPassword2)) {
            throw new CmsException(ErrorCode.INPUT_TWO_PASSWORD_IS_DIFF);
        }

        if (!Md5Util.MD5(oldPassword).equals(user.getPassword())) {
            throw new CmsException(ErrorCode.OLD_PASSWORD_IS_WRONG);
        }
        user.setPassword(Md5Util.MD5(newPassword1));
        int rows = baseMapper.updateById(user);
        if (rows == 0) {
            throw new CmsException(ErrorCode.DATA_BASE_EXCEPTION);
        } else {
            session.setAttribute(request.getHeader("access_token"), user);
            session.setMaxInactiveInterval(30 * 60);
        }
    }


}
